#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 命令常量
enum {
    CMD_QUIT,   // 退出
    CMD_READ,   // 读取
    CMD_SAVE,   // 保存
    CMD_PRINT,  // 打印
    CMD_QUERY,  // 查询
    CMD_INSERT, // 添加
    CMD_UPDATE, // 修改
    CMD_DELETE, // 删除
    CMD_SORT,   // 排序
    CMD_CHART,  // 图表
};

// 函数声明
void init(void);         // 程序启动
void quit(void);         // 程序退出
void display_menu(void); // 显示命令菜单
int make_choice(void);   // 选择命令
int confirm(const char* msg);

void read_data(void);    // 读取
void save_data(void);    // 保存
void print_data(void);   // 打印
void query_data(void);   // 查询
void add_data(void);     // 添加
void update_data(void);  // 修改
void delete_data(void);  // 删除
void sort_data(void);    // 排序
void make_chart(void);   // 图表

// 主程序
int main(void)
{
    init();
    for (;;) {
        display_menu();
        int c = make_choice();
        switch (c) {
        case CMD_READ:
            read_data();
            break;
        case CMD_SAVE:
            save_data();
            break;
        case CMD_PRINT:
            print_data();
            break;
        case CMD_QUERY:
            query_data();
            break;
        case CMD_INSERT:
            add_data();
            break;
        case CMD_UPDATE:
            update_data();
            break;
        case CMD_DELETE:
            delete_data();
            break;
        case CMD_SORT:
            sort_data();
            break;
        case CMD_CHART:
            make_chart();
            break;
        case CMD_QUIT:
            if (confirm("确定要退出吗？")) quit();
            break;
        default:
            printf("命令错误，请重新选择\n");
        }
    }
    return 0;
}

void init(void)
{
    puts("库存管理系统启动");
}

void quit(void)
{
    puts("程序退出");
    exit(EXIT_SUCCESS);
}

void display_menu(void)
{
    printf("\n%d 读取 | %d 保存 | %d 打印 | %d 查询 | %d 添加\n"
           "%d 修改 | %d 删除 | %d 排序 | %d 图表 | %d 退出\n\n",
        CMD_READ, CMD_SAVE, CMD_PRINT, CMD_QUERY, CMD_INSERT,
        CMD_UPDATE, CMD_DELETE, CMD_SORT, CMD_CHART, CMD_QUIT);
}

int make_choice(void)
{
    int choice;
    int ok = 0;

    while (!ok) {
        printf("请选择：");
        ok = scanf("%d", &choice);
        scanf("%*[^\n]");
    }

    return choice;
}

int confirm(const char* msg)
{
    char c = 'n';
    printf("%s(Y/N): ", msg);
    scanf(" %c%*[^\n]", &c);
    return c == 'y' || c == 'Y';
}

// 零件库存储结构
#define NAME_LEN 31
#define MAX_PARTS 100

struct part {
    int number;
    char name[NAME_LEN + 1];
    int on_hand;
};

static struct part inventory[MAX_PARTS];
static int num_parts = 0;


int find_part(int part_number)
{
    for (int i = 0; i < num_parts; i++)
        if (inventory[i].number == part_number)
            return i;

    return -1; // not found
}

void query_data(void)
{
    int part_number;

    printf("输入零件编号：");
    scanf("%d", &part_number);

    int index = find_part(part_number);

    if (index == -1) {
        printf("零件不存在.\n");
    } else {
        printf("零件编号：%d\n", inventory[index].number);
        printf("零件名称：%s\n", inventory[index].name);
        printf("零件库存：%d\n", inventory[index].on_hand);
    }
}

void add_data(void)
{
    int part_number, on_hand;
    char name[NAME_LEN + 1];

    printf("输入零件编号：");
    scanf("%d", &part_number);

    if (find_part(part_number) != -1) {
        printf("零件已存在.\n");
        return;
    }

    printf("输入零件名：");
    scanf("%s", name);
    printf("输入库存数：");
    scanf("%d", &on_hand);

    if (num_parts >= MAX_PARTS) {
        printf("库存已满，无法添加新零件。\n");
        return;
    }

    inventory[num_parts].number = part_number;

    strcpy(inventory[num_parts].name, name);
    inventory[num_parts].on_hand = on_hand;
    num_parts++;

    printf("零件 %d 已添加\n", part_number);
}

void update_data(void)
{
    int part_number;
    printf("输入零件编号：");
    scanf("%d", &part_number);
    
    int index = find_part(part_number);
    if (index == -1) {
        printf("零件不存在\n");
        return;
    }
    
    printf("输入零件名：");
    scanf("%*[\n]"); // Clear any remaining newline in input buffer
    fgets(inventory[index].name, NAME_LEN, stdin);
    // Remove trailing newline if present
    inventory[index].name[strcspn(inventory[index].name, "\n")] = '\0';
    
    printf("输入库存数：");
    scanf("%d", &inventory[index].on_hand);
    
    printf("零件 %d 已更新\n", part_number);
}

void delete_data(void)
{
    int part_number;
    printf("输入零件编号：");
    scanf("%d", &part_number);
    scanf("%*[^\n]"); // 清除输入缓冲区
    
    int i = find_part(part_number);
    if (i == -1) {
        printf("零件不存在.\n");
        return;
    }
    
    // 删除零件（通过将后续元素前移覆盖）
    for (int j = i; j < num_parts - 1; j++) {
        inventory[j] = inventory[j + 1];
    }
    num_parts--;
    
    printf("零件 %d 已删除\n", part_number);
}

void read_data(void)
{
    char filename[100];
    FILE *file;
    int part_number, on_hand;
    char name[NAME_LEN + 1];

    printf("读取数据\n");
    printf("请输入文件名：");
    scanf("%s", filename);

    // 尝试打开文件
    file = fopen(filename, "r");
    if (file == NULL) {
        // 文件不存在，输出错误信息
        perror(filename);
        return;
    }

    num_parts = 0; // 重置库存数量
    // 从 CSV 文件中读取记录
    while (fscanf(file, "%d,%[^,],%d", &part_number, name, &on_hand) == 3) {
        if (num_parts < MAX_PARTS) {
            inventory[num_parts].number = part_number;
            strcpy(inventory[num_parts].name, name);
            inventory[num_parts].on_hand = on_hand;
            num_parts++;
        } else {
            // 库存已满，无法继续添加
            printf("库存已满，无法读取更多记录。\n");
            break;
        }
    }

    printf("读取 %d 记录\n", num_parts);
    fclose(file);
}

void save_data(void) 
{
    char filename[100];
    FILE *file;
    int i;

    printf("保存数据\n");
    printf("请输入文件名：");
    scanf("%s", filename);

    // 尝试创建并打开文件
    file = fopen(filename, "w");
    if (file == NULL) {
        perror(filename);
        return;
    }

    // 将库存数据写入 CSV 文件
    for (i = 0; i < num_parts; i++) {
        fprintf(file, "%d,%s,%d\n", 
                inventory[i].number, 
                inventory[i].name, 
                inventory[i].on_hand);
    }

    printf("保存 %d 条记录\n", num_parts);
    fclose(file);
}

void print_data(void)
{
    int part_number;
    printf("输入零件编号：");
    scanf("%d", &part_number);
    
    int index = find_part(part_number);
    if (index == -1) {
        printf("零件不存在\n");
        return;
    }
    
    printf("零件编号：%d\n", inventory[index].number);
    printf("零件名称：%s\n", inventory[index].name);
    printf("零件库存：%d\n", inventory[index].on_hand);
}

void sort_data(void)
{
     struct part temp;
    int swapped;
    for (int i = 0; i < num_parts - 1; i++) {
        swapped = 0;
        for (int j = 0; j < num_parts - i - 1; j++) {
            if (inventory[j].number > inventory[j+1].number) {
                // 交换零件记录
                temp = inventory[j];
                inventory[j] = inventory[j+1];
                inventory[j+1] = temp;
                swapped = 1;
            }
        }
        if (swapped == 0) break; // 提前退出排序
    }
    printf("排序已完成\n");
}

void make_chart(void)
{
    puts("图表");
    for (int i = 0; i < num_parts; i++) {
        printf("    %d : %-10s| ", inventory[i].number, inventory[i].name);
        for (int j = 0; j < inventory[i].on_hand; j++) {
            printf("*");
        }
        printf(" (%d)\n", inventory[i].on_hand);
    }
}
